Previous: Fetching Device Contacts using ABAddressBook framework in iOS
In our previous article we already learn about the code of address book framework step-by-step. So here we will not talk in detail about the address book only some important point. In iOS device the contacts application allows users to manage their contacts. And the address book framework allows us to get access to the address book database on the device. In our application we will display only name, phone number with its type.
To create contact sync app using address book framework follow the steps:
1. Open Xcode and create a new Single View Application. In the product name field enter “Contact-Sync-Demo”. Check mark on the iPhone option and Automatic Reference Counting and un-check the Storyboard.
2. Ok, First of all we will go to add some contacts into the address book. For this goto left-top on the Xcode and click on the Run button, after that simulator will be open. On the simulator open the simulator contacts app and click on “+” button on the top-right of the screen to add contact and add contact like below and click on 'Done' button, after that you can a contact now added like below:
3. Now, click on the Contact-Sync-Demo project and under the
Summary section, click on + button
under the ‘Linked Frameworks and Libraries’ and add ‘AddressBook.framework’,
like this:
4. Now, click on the ViewController.xib file and drag and drop
table view from the Objects library. Like this:
5. Now, create new class with name ‘Person’ and its parent will be NSObject. Select Person.h file and between the @interface and @end add some properties such as Id, firstName, middleName, lastName, contactNumber, contactType, modificationDate, like this:
@property (nonatomic, strong) NSNumber *Id;
@property (nonatomic, strong) NSString *firstName;
@property (nonatomic, strong) NSString *middleName;
@property (nonatomic, strong) NSString *lastName;
@property (nonatomic, strong) NSString *contactNumber;
@property (nonatomic, strong) NSString *contactType;
@property (nonatomic, strong) NSDate *modificationDate;
6. Now, select AppDelegate.h file and add some properties of ViewController, ABAddressBookRef, NSMutableArray, and a method getContactsFromAddressBook: like this:
@property (strong, nonatomic) ViewController *viewController;
@property ABAddressBookRef addressBook;
@property(nonatomic, strong) NSMutableArray *tableData;
- (NSMutableArray*)getContactsFromAddressBook:(ABAddressBookRef*)phoneContacts;
7. Now, add an m character in the extension of AppDelegate.m file after its name will be AppDelegate.mm, we change it because we are going to use C/C++ methods and some other codes in this file so .m file will not handle the C/C++ code so we add and m character in this file.
8. Now, in the AppDelegate.mm file add these code in the didFinishLaunchingWithOptions: method:
_addressBook = ABAddressBookCreate();
Above code will be used to get and store the address book reference into the _addressBook; and implement the getContactsFromAddressBook: method that is already declared in the header file and call it in the didFinishLaunchingWithOptions: method, with the help of getContactsFromAddressBook: method we will fetch all the contacts from the device at first time when it will call, we will call it like this:
[self getContactsFromAddressBook];
9. Now, select the ViewController.h file and create an outlet for the table view and named it TableViewRef, like this:
@property (strong, nonatomic) IBOutlet UITableView *TableViewRef;
That’s it, our device contacts fetch coding is completed, and below we are provided
our complete code of our app. But the code we are adding here is not completed
we will complete it in our next article. Here our main motive is to get device
contacts on our app.
Now, run the application by clicking on the run button on the Xcode, in our app we
are displaying person name with its mobile no and type, like this:
Here is the Complete code of our application:
AppDelegate.h file
#import <UIKit/UIKit.h>
#import <AddressBook/AddressBook.h>
#import "Person.h"
@interface AppDelegate : UIResponder< UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) ViewController *viewController;
@property ABAddressBookRef addressBook;
@property(nonatomic, strong) NSMutableArray *tableData;
- (NSMutableArray*)getContactsFromAddressBook:(ABAddressBookRef*)phoneContacts;
@end
AppDelegate.mm file
#import "AppDelegate.h"
#import "ViewController.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
__block BOOL accessGranted = NO;
_addressBook = ABAddressBookCreate();
if (&ABAddressBookRequestAccessWithCompletion != NULL) {
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
ABAddressBookRequestAccessWithCompletion(_addressBook, ^(bool granted, CFErrorRef error) {
accessGranted = granted;
dispatch_semaphore_signal(semaphore);
});
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
}
ABAddressBookRegisterExternalChangeCallback(_addressBook, addressBookChanged, (__bridge void *)(self));
// Override point for customization after application launch.
self.viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];
UINavigationController *navController = [[UINavigationController alloc] initWithRoot ViewController:self.viewController];
self.window.rootViewController = navController;
self.tableData = [[NSMutableArray alloc] init];
[self getContactsFromAddressBook];
[self.window makeKeyAndVisible];
return YES;
}
- (void)getContactsFromAddressBook
{
if(self.tableData.count<=0){
CFErrorRef error = nil;
ABAddressBookRef phoneContacts = ABAddressBookCreateWithOptions(NULL,& error);
if (phoneContacts != nil) {
NSArray *allContacts = (__bridge_transfer NSArray *)ABAddressBookCopyArrayOf AllPeople(phoneContacts);
NSUInteger i = 0;
for(i = 0; i < [allContacts count]; i++)
{
ABRecordRef contactPerson = (__bridge ABRecordRef)allContacts[i];
NSNumber *contactId = [NSNumber numberWithInt:ABRecordGetRecordID(contactPerson)];
NSString *firstName = (__bridge_transfer NSString *)ABRecordCopyValue(contactPerson, kABPersonFirstNameProperty);
NSString *middleName = (__bridge_transfer NSString *)ABRecordCopyValue(contactPerson, kABPersonMiddleNameProperty);
NSString *lastName = (__bridge_transfer NSString *)ABRecordCopyValue(contact Person, kABPersonLastNameProperty);
NSDate *modificationDate = (__bridge_transfer NSDate *)ABRecordCopyValue(contactPerson, kABPersonModificationDateProperty);
// Getting no of person contact numbers
ABMultiValueRef numbersArr = ABRecordCopyValue(contactPerson, kABPersonPhoneProperty);
NSUInteger j = 0;
for(j = 0; j < ABMultiValueGetCount(numbersArr); j++)
{
NSString *cellN = (__bridge_transfer NSString *)ABMultiValueCopyValueAtIndex(numbersArr, j);
NSString *cellT =(__bridge NSString*)ABAddressBookCopyLocalizedLabel( AB MultiValueCopyLabelAtIndex(numbersArr, j));
Person *person = [Person new];
person.Id = contactId;
person.firstName = firstName;
person.middleName = middleName;
person.lastName = lastName;
person.modificationDate = modificationDate;
person.contactNumber = cellN;
person.contactType = cellT;
[self.tableData addObject:person];
}
}
CFRelease(phoneContacts);
} else {
NSLog(@"Error reading Address Book");
}
}
}
.
.
.
@end
ViewController.h file
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
@interface ViewController : UIViewController<ContactDelegate>
@property(nonatomic,strong) AppDelegate *obj;
@property (strong, nonatomic) IBOutlet UITableView *TableViewRef;
@end
ViewController.m file
#import "AppDelegate.h"
#import "ViewController.h"
#import "Person.h"
#import <AddressBook/AddressBook.h>
#define allTrim(object) [object stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]
@interface ViewController ()<UITableViewDataSource, UITableViewDelegate>
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.title = @"Contacts";
_obj = (AppDelegate *)[UIApplication sharedApplication].delegate;
_obj.delegate=self;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// NSLog(@"%d",[[AppDelegate GetData] count]);
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"firstName" ascending:YES];
NSArray *array = [NSArray arrayWithObject:sortDescriptor];
[_obj.tableData sortUsingDescriptors:array];
return [_obj.tableData count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *identifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if(cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identifier];
}
Person *person = [_obj.tableData objectAtIndex:indexPath.row];
NSString *personName;
if(person.firstName.length != 0&& person.lastName.length != 0) {
personName = [[NSString alloc] initWithFormat:@"%@ %@",person.firstName,person.lastName];
}
else if (person.lastName.length == 0) {
personName = person.firstName;
}
else {
personName = person.lastName;
cell.textLabel.text = personName;
cell.detailTextLabel.text = [[NSString alloc] initWithFormat:@"%@: %@",person.contactType,person.contactNumber];
return cell;
}
@end
Person.h file
#import <Foundation/Foundation.h>
@interface Person : NSObject
@property (nonatomic, strong) NSNumber *Id;
@property (nonatomic, strong) NSString *firstName;
@property (nonatomic, strong) NSString *middleName;
@property (nonatomic, strong) NSString *lastName;
@property (nonatomic, strong) NSString *contactNumber;
@property (nonatomic, strong) NSString *contactType;
@property (nonatomic, strong) NSDate *modificationDate;
@end
Person.m file
#import "Person.h"
@implementation Person
@end
Leave Comment